package com.hanock.sm.fork2d;

import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;



public class Fork2dView extends GLSurfaceView {
	
	private static final int TIMER_PERIOD_DEFAULT = 35;
	
	private Fork2dContext fork2dContext;
	private Fork2dRenderer fork2dRenderer;
	private int width;
	private int height;
	
	private int timerPeriod;
	
	private boolean sceneStarted;
	
	private Timer timer;
	

	public Fork2dView(Context context) {
		super(context);
		creator();
	}
	
	public Fork2dView(Context context, AttributeSet attrs) {
		super(context, attrs);
		creator();
	}

	private void creator(){
		width = height = 100; // prevent zero
		
		TextureManager.createInstance(getContext());
		
		fork2dContext = new Fork2dContext(getContext());
		fork2dRenderer = new Fork2dRenderer(fork2dContext);
		
		//setEGLConfigChooser(4,4,4,4,16,0);
		//setBackgroundColor(Color.BLACK);
		setRenderer(fork2dRenderer);
		setRenderMode(RENDERMODE_WHEN_DIRTY);
	}
	
	/**
	 * 액티비티에서 onPause가 호출되면 호출되는 함수
	 */
	@Override
	public void onPause() {
		//super.onPause();
		
		Object sync = fork2dContext.getMonitor();
		Scene scene = SceneManager.getInstance().getCurrentScene();
		if (scene != null){
			synchronized (sync) {
				scene.onActivityPause();
			}
		}
		
		if (timer != null){
			timer.cancel();
			timer = null;
		}
	}
	
	/**
	 * 액티비티에서 onResume가 호출되면 호출되는 함수
	 */
	@Override
	public void onResume() {
		//super.onResume();
		
		Object sync = fork2dContext.getMonitor();
		Scene scene = SceneManager.getInstance().getCurrentScene();
		if (scene != null){
			synchronized (sync) {
				scene.onActivityResume();
			}
		}
		
		if (timer == null && sceneStarted){
			timer = new Timer();
			timer.scheduleAtFixedRate(new Fork2dTimerTask(), 0, timerPeriod);
		}
	}
	
	public void onDestroy(){
		
		if (timer != null){
			timer.cancel();
			timer = null;
		}
	}
	
	public void onBackPressed(){
		
		Object sync = fork2dContext.getMonitor();
		Scene scene = SceneManager.getInstance().getCurrentScene();
		if (scene != null){
			synchronized (sync) {
				scene.onBackPressed();
			}
		}
	}
	
	public void onMenu(int code){
		
		Object sync = fork2dContext.getMonitor();
		Scene scene = SceneManager.getInstance().getCurrentScene();
		if (scene != null){
			synchronized (sync) {
				scene.onMenu(code);
			}
		}
	}
	
	/**
	 * 반드시 한 번만 호출 
	 */
	public void startScene(Scene scene){
		startScene(scene, TIMER_PERIOD_DEFAULT);
	}
	
	/**
	 * must called once
	 */
	public void startScene(Scene scene, int timerPeriod){
		if (sceneStarted)
			return;
		
		this.timerPeriod = timerPeriod;
		
		SceneManager.getInstance().pushScene(scene);
		sceneStarted = true;
		
		if (timer == null){
			timer = new Timer();
			timer.scheduleAtFixedRate(new Fork2dTimerTask(), 0, timerPeriod);
		}
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
		super.surfaceChanged(holder, format, w, h);
		this.width = w;
		this.height = h;
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		int action = event.getAction();
		TouchMode mode = null;
		
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			mode = TouchMode.DOWN;
			break;
			
		case MotionEvent.ACTION_MOVE:
			mode = TouchMode.MOVE;
			break;
			
		case MotionEvent.ACTION_UP:
			mode = TouchMode.UP;
			break;

		default:
			mode = null;
			break;
			
		}
		
		
		// 씬으로 터치 이벤트를 전달 
		if (mode != null){
			
			Scene scene = SceneManager.getInstance().getCurrentScene();
			ViewportInfo viewportInfo = fork2dRenderer.getViewportInfo();
			
			if (scene == null)
				return false;
			
			if (viewportInfo.width == 0 || viewportInfo.height == 0)
				return false;
			
			float x = event.getX();
			float y = event.getY();
			
			x = 1f*(x - viewportInfo.left)*scene.getWidth()/viewportInfo.width;
			y = 1f*(height - y - viewportInfo.bottom)*scene.getHeight()/viewportInfo.height;
			
			Object sync = fork2dContext.getMonitor();
			synchronized (sync) {
				scene.visit(x, y, mode);
			}
			
			return true;
		}
		else{
			return false;
		}
	}

	public Fork2dContext getFork2dContext() {
		return fork2dContext;
	}
	
	
	
	private class Fork2dTimerTask extends TimerTask{
		
		private int c;
		private long time;
		
		public Fork2dTimerTask() {
			time = c = 0;
		}
		
		/**
		 * 타이머 간격은 timerPeriod 멤버, startScene 함수 참조
		 * 
		 */
		@Override
		public void run() {
			
			//
			if (time == 0)
				time = SystemClock.elapsedRealtime();
			
			//
			Object sync = fork2dContext.getMonitor();
			Scene scene = SceneManager.getInstance().getCurrentScene();
			if (scene != null){
				synchronized (sync) {
					scene.visit(timerPeriod);
					c++;
				}
			}
			
			// ups : 업데이트 퍼 세컨드
			long cur = SystemClock.elapsedRealtime();
			if (cur > time + 5000){
				Log.i("test", "ups: " + c/5f);
				c = 0;
				time = cur;
			}
			
			//
			requestRender();
		}
	}
	
}






























